

<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <title>NESASM</title>
    <style>
    html,body{font-size:14px; color:#444;} 
    a {text-decoration: none; color:blue;}
    a:hover{color:red;}
    .main{margin:0 auto; width:960px;}
    .box{border:1px solid #eee;}
    </style>
</head>

<body>

<div class="main">
<p>【啥？！】
</p><p>然。今天将创建并载入调色板。为了创建调色板，我们将使用程序PAL.exe，我在第一天给你的那个zip文件中有这个。运行它，你将看到一个窗口，有32个灰色的盒子，你可以从底部彩色盒子中选取绘制颜色填充它们。当你制作调色板时一定要保证每行第一个颜色是黑色，否则你后面制作背景和主角时会看到很多意外的东西。
</p><p>保存调色板为our.pal。
</p><p>*新的段落：什么是调色板，简单直接*
</p><p>*如果我本文后面说了一些和这段矛盾的东西，忽略它*
</p><p>调色板基本上是一组可供选择的颜色。我们的调色板有32种颜色，占用32字节（每个颜色占1字节）。16种颜色是为主角准备的，16种为背景准备。尽管你可以选择16种，但实际上每个主角只能选4种，背景的每个16x16像素块也只能选4种。现在说起来太复杂，所以我们后面详细介绍。
</p><p>*新的段落结束*
</p><p>【怎样载入调色板】
</p><p>我们通过写入两个内存映射寄存器来为PPU载入调色板。首先向$2006写两次，作为调色板载入的完整首地址（$3F00），然后向$2007写入32字节调色板数据。
</p><p>然而，我们载入调色板之前，应该先学习一点其他知识。
</p><p>【变址寻址】
</p><p>你应该记得第一天和第二天，我说X，Y寄存器可以用于变址寻址。这里你会看到怎么做。
</p><p>;假设X等于6
</p><p>lda $2002, x; 从内存地址($2002+6)处载入数据，即从$2008处
</p><p>;假设Y等于9
</p><p>lda $2000, y; 从内存地址$2009处载入数据
</p><p>注意你可以载入到任意寄存器，不仅仅是A
</p><p>【其他】
</p><p>你需要知道的是：load和store指令可以采用一个标签作为基地址。代码如下：
</p><p>somelabel: .incbin "our.pal";包含一个pal文件，标签为它的首地址
</p><p>lda somelabel, x; 从标签表示的地址+X处向A载入一个值
</p><p>例子程序只写了怎么向A中载入值，其他X，Y是类似的。如果你读过我的Intel汇编教程（http://patater.com/gbaguy/x86asm.htm）或其他基本汇编书籍/文章，你应该已经知道标签的作用。这是基础，不用我多说。
</p><p>【载入调色板】
</p><p>为了不让我的键盘一个劲敲，还是让代码自己说话吧。
</p><p>    lda #$3F   ; 
</p><p>    sta $2006  ; 
</p><p>    lda #$00   ; 
</p><p>    sta $2006  ; 
</p><p>    ; 上面这4行告诉$2006:我们后面准备向$3F00地址处写一些东西，由于一次只能写一个字节，所以上面需要store两次
</p><p>    ldx #$00   ; X <- 0
</p><p>loadpal:   ; 注意标签不用缩进，后面跟着一个冒号
</p><p>    lda ourpal, x   ; 从地址ourpal+x处载入调色板数据到A.
</p><p>    sta $2007       ; 写到$2007里面，PPU会自己放到上面我们设置的首地址$3F00
</p><p>    ; 
</p><p>    inx    ; 没见过这个指令？就是Increment X的意思，X++
</p><p>    ; 
</p><p>    cpx #32   ; 比较X和32，也就是数一下已经写入多少调色板数据了.
</p><p>    bne loadpal  ; BNE表示如果不相等就跳转,所以X不等于32时会跳到loadpal位置，而X==32时则循环结束，调色板载入结束。
</p><p>假设ourpal是一个定义在汇编源文件后面的标签
</p><p>ourpal: .incbin "our.pal"; 为我们的调色板贴标签，用于载入代码；
</p><p>明天我们将完整代码文件放到一起，并显示我们的主角。
</p><p>【新指令】
</p><p>上面代码看到了三个新指令：
</p><p>INX——X增加1；另外INY表示Y增加1；但没有INA，我听说6502设计者忘了这个。在SNES中增加了INA指令，用了下一代6502（65C02）
</p><p>CPX——比较X和另外的值。还有CPY和CPA。这里值只能是立即数，不允许内存寻址。
</p><p>BNE——如果上一条CPk（k = A, X, Y）指令结果为“不等”，则跳到一个标签处。另外还有BEQ，当结果相等才跳转。后面我还会详细介绍。
</p><p>【今日回顾】
</p><p>载入调色板是十分重要的，因为如果没有它，后面背景显示、主角显示都扯淡。
</p><p>载入调色板是十分简单的，因为它就是它，一旦写好了就不用动，不需要你再为它做什么。
</p><p>明天我们讲主角显示。
</p><p>NES见鬼去吧。睡了。
</p></div>
</body>
</html>
